/**
 * File		: Color.java
 * Subject	: Represents an RGBA color value
 * Author	: Isaac Parenteau (locus2k@gmail.com)
 * Date		: April 16th, 2011
 */
package src.project.util;

public class Color {
	
	public static final String name = Color.class.getSimpleName();
	
	public static Color Red = new Color(255, 0, 0, 255);
	public static Color Green = new Color(0, 255, 0, 255);
	public static Color Blue = new Color(0, 0, 255, 255);
	public static Color White = new Color(255, 255, 255, 255);
	public static Color Black = new Color(0, 0, 0, 255);
	public static Color Transparent = new Color(255 ,255, 255, 0);
	
	public int R;
	public int G;
	public int B;
	public int A;
	
	/**
	 * Default Constructor
	 */
	public Color(){
		this(0, 0, 0, 255);
	}
	
	/**
	 * Constructor that takes a red, green and blue value
	 * @param r Red value
	 * @param g Green value
	 * @param b Blue value
	 */
	public Color(int r, int g, int b){
		this(r, g, b, 255);
	}
	
	/**
	 * Constructor that takes a red, green, blue and alpha value
	 * @param r Red value
	 * @param g Green value
	 * @param b Blue value
	 * @param a Alpha value
	 */
	public Color(int r, int g, int b, int a){
		R = r;
		G = g;
		B = b;
		A = a;
	}
	
	/**
	 * Converts a byte array to a color
	 * @param pixels pixel to convert
	 * @return color of the pixel
	 */
	public static Color getPixelColor(byte[] pixels) {
				
		int[] color = new int[pixels.length];
		
		for(int i = 0; i < color.length; i++)
			color[i] = (int)(pixels[i] & 255);

		return  new Color(color[0], color[1], color[2], color[3]);
	}

	/**
	 * Adds shade to the color
	 * @param r red value to shade by
	 * @param g green value to shade by
	 * @param b blue value to shade b y
	 * @return shaded color
	 */
	public Color shade(int r, int g, int b){
		return shade(r, g, b, 0);
	}
	
	/**
	 * Adds the same shade value to RGB
	 * @param shade shade value
	 * @return shaded color
	 */
	public Color shade(int shade){
		return shade(shade, shade, shade);
	}
	
	/**
	 * Adds shade to the color
	 * @param r red value to shade by
	 * @param g green value to shade by
	 * @param b blue value to shade by
	 * @param a alpha value to shade by
	 * @return shaded color
	 */
	public Color shade(int r, int g, int b, int a) {
		int red = this.R + r > 255 ? 255 : this.R + r;
		int green = this.G + g > 255 ? 255 : this.G + g;
		int blue = this.B + b > 255 ? 255 : this.B + b;
		int alpha = this.A + a > 255 ? 255 : this.A + a;
		
		return new Color(red, green, blue, alpha);
	}
	
	/**
	 * Checks to see if two colors are equal
	 * @param a color a
	 * @param b color b
	 * @param redOffset red offset
	 * @param greenOffset green offset
	 * @param blueOffset blue offset
	 * @return equal
	 */
	public static boolean equal(Color a,  Color b, int redOffset, 
			int greenOffset, int blueOffset){
		
		boolean isEqual = true;
		
		isEqual = isEqual && (b.R >= a.R && b.R <= a.R + redOffset);
		isEqual = isEqual && (b.G >= a.G && b.G <= a.G + blueOffset);
		isEqual = isEqual && (b.B >= a.B && b.B <= a.B + greenOffset);
	
		return isEqual;
	}
	
	/**
	 * Checks to see if two colors are equal
	 * @param a color a
	 * @param b color b
	 * @param offset offset
	 * @return equal or not
	 */
	public static boolean equal(Color a, Color b, int offset){
		
		return equal(a, b, offset, offset, offset);
	}
	

	/**
	 * Checks to see if a color is a type of another color
	 * @param color color to test
	 * @return
	 */
	public boolean isTypeOf(Color color) {
		
		boolean isTypeOf = true;
		
		isTypeOf = isTypeOf && (Math.abs(R - color.R) < 10);
		isTypeOf = isTypeOf && (Math.abs(G - color.G)< 10);
		isTypeOf = isTypeOf && (Math.abs(B - color.B) < 10);
	
		return isTypeOf;
	}
	
	/**
	 * prints out the color value
	 */
	public String toString(){
		return String.format("[Red: %d][Green: %d][Blue: %d][Alpha: %d]\n",
				R, G, B, A);
	}

}
